﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPFTetris.TetrisBoard
{
    /// <summary>
    /// Draws a tetris piece.
    /// </summary>
    public partial class TetrisPiece : UserControl
    {
        public static DependencyProperty TetrisMapProperty = DependencyProperty.Register("TetrisMap", typeof(string), typeof(TetrisPiece), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsRender));
        public static DependencyProperty PieceWidthProperty = DependencyProperty.Register("PieceWidth", typeof(int), typeof(TetrisPiece), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsRender));
        public static DependencyProperty PieceHeightProperty = DependencyProperty.Register("PieceHeight", typeof(int), typeof(TetrisPiece), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsRender));
        public static DependencyProperty PieceColorProperty = DependencyProperty.Register("PieceColor", typeof(Brush), typeof(TetrisPiece), new FrameworkPropertyMetadata(Brushes.LightSteelBlue, FrameworkPropertyMetadataOptions.AffectsRender));

        private int[,] tetrisMapArray;

        public TetrisPiece()
        {
            InitializeComponent();
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            ExtractTetrisMap();
            RenderFromMap(drawingContext);
            base.OnRender(drawingContext);
        }

        private void RenderFromMap(DrawingContext drawingContext)
        {
            this.Width = TetrisBoard.unitSizeInPixels * PieceWidth;
            this.Height = TetrisBoard.unitSizeInPixels * PieceHeight;

            int width = PieceWidth, height = PieceHeight;

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                    if (tetrisMapArray[i, j] == 1)
                    {
                        drawingContext.DrawRectangle(PieceColor, new Pen(Brushes.Black, 1), new Rect(i * TetrisBoard.unitSizeInPixels, j * TetrisBoard.unitSizeInPixels, TetrisBoard.unitSizeInPixels, TetrisBoard.unitSizeInPixels));
                    }
            }
        }

        public string TetrisMap
        {
            get { return (string)GetValue(TetrisMapProperty); }
            set
            {
                SetValue(TetrisMapProperty, value);
            }
        }

        public int PieceWidth
        {
            get { return (int)GetValue(PieceWidthProperty); }
            set
            {
                SetValue(PieceWidthProperty, value);
            }
        }

        public int PieceHeight
        {
            get { return (int)GetValue(PieceHeightProperty); }
            set
            {
                SetValue(PieceHeightProperty, value);
            }
        }

        public Brush PieceColor
        {
            get { return (Brush)GetValue(PieceColorProperty); }
            set
            {
                SetValue(PieceColorProperty, value);
            }
        }

        public int[,] TetrisMapArray
        {
            get
            {
                return tetrisMapArray;
            }
        }

        private int[] downBorder;
        public int[] DownBorderHeights
        {
            get
            {
                if (downBorder == null)
                {
                    downBorder = new int[PieceWidth];

                    for (int i = 0; i < PieceWidth; i++)
                    {
                        for (int j = PieceHeight - 1; j >= 0; j--)
                        {
                            if (tetrisMapArray[i, j] != 0)
                            {
                                downBorder[i] = PieceHeight - j;
                                break;
                            }
                        }
                    }
                }

                return downBorder;
            }
        }

        private int[] upBorder;
        public int[] UpBorderHeights
        {
            get
            {
                if (upBorder == null)
                {
                    upBorder = new int[PieceWidth];

                    for (int i = 0; i < PieceWidth; i++)
                    {
                        for (int j = 0; j < PieceHeight; j++)
                        {
                            if (tetrisMapArray[i, j] != 0)
                            {
                                upBorder[i] = PieceHeight - j;
                                break;
                            }
                        }
                    }
                }

                return upBorder;
            }
        }


        private void ExtractTetrisMap()
        {
            if (tetrisMapArray == null)
            {
                tetrisMapArray = new int[PieceWidth, PieceHeight];

                string[] tokens = TetrisMap.Split();
                int width = PieceWidth, height = PieceHeight, current = 0;

                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        tetrisMapArray[i, j] = Int32.Parse(tokens[current++]);
                    }
                }
            }
        }

        public static TetrisPiece Clone(TetrisPiece tetrisPiece)
        {
            TetrisPiece tp = new TetrisPiece();
            tp.PieceWidth = tetrisPiece.PieceWidth;
            tp.PieceHeight = tetrisPiece.PieceHeight;
            tp.PieceColor = tetrisPiece.PieceColor;
            tp.TetrisMap = tetrisPiece.TetrisMap;

            return tp;
        }
    }
}
